﻿using DG.Tweening;
using UnityEngine;

public partial class PlayerController : MonoBehaviour
{

    private bool _moveEnabled = true;
    private bool _jumpEnabled = true;
    private bool _gravityEnabled = true;

    // 玩家受伤时，在伤害物的左边
    private bool _playerHurtOnLeft;

    void Movement()
    {
        Move();
        Jump();
        Hurt();

        if (playerData.enableDash)
        {
            Dash();
        }
    }

    /**
     * Mathf.SmoothDamp 从 A 速度到 B 速度的平滑插值
     */
    void Move()
    {
        if (!_moveEnabled)
        {
            return;
        }
        float horizontal = Input.GetAxis("Horizontal");
        if (horizontal > playerData.inputRebound.x)
        {
            isMoving = true;
            isFaceToRight = true;
            float xVelocity = runSpeedRate * playerData.runSpeed * Time.fixedDeltaTime;
            if (rb.velocity.x < xVelocity)
            {
                rb.velocity = new Vector2(Mathf.SmoothDamp(rb.velocity.x, xVelocity, ref currentVelocityX, playerData.accelerateTime), rb.velocity.y);
            }
        }
        else if (horizontal < -playerData.inputRebound.x)
        {
            isMoving = true;
            isFaceToRight = false;
            float xVelocity = -runSpeedRate * playerData.runSpeed * Time.fixedDeltaTime;
            if (rb.velocity.x > xVelocity)
            {
                rb.velocity = new Vector2(Mathf.SmoothDamp(rb.velocity.x, xVelocity, ref currentVelocityX, playerData.accelerateTime), rb.velocity.y);
            }
        }
        else
        {
            isMoving = false;
            rb.velocity = new Vector2(Mathf.SmoothDamp(rb.velocity.x, 0, ref currentVelocityX, playerData.decelerateTime), rb.velocity.y);
        }
    }


    void Jump()
    {
        isOnGround = CheckOnGround();
        if (!_jumpEnabled)
        {
            return;
        }
        if (!isJumping && isOnGround && Input.GetAxis("Jump") == 1)
        {
            rb.velocity = new Vector2(rb.velocity.x, playerData.jumpSpeed);
            isJumping = true;
        }
        if (isOnGround && Input.GetAxis("Jump") == 0)
        {
            isJumping = false;
        }

        GravityAdjustment();
    }

    // 重力调整
    void GravityAdjustment()
    {
        if (!_gravityEnabled)
        {
            return;
        }
        if (!isOnGround && rb.velocity.y < 0)       // 下坠，增加判断isOnGround是为了修复rb.velocity.y不归零导致一直在下落状态的问题
        {
            isFalling = true;
            // 加速下坠
            rb.velocity += Vector2.up * Physics2D.gravity.y * (playerData.fallMultiplier - 1) * Time.fixedDeltaTime;
        }
        else if (!isOnGround && rb.velocity.y > 0)     // 上升，增加判断isOnGround是为了修复rb.velocity.y不归零的问题
        {
            isFalling = false;
            if (Input.GetAxis("Jump") != 1)     // 没有按住跳跃键
            {
                // 减缓上升
                rb.velocity += Vector2.up * Physics2D.gravity.y * (playerData.lowJumpMultiplier - 1) * Time.fixedDeltaTime;
            }
        }
        else
        {
            isFalling = false;
        }
    }

    void Dash()
    {
        bool isPressedDash = IsInputDash();
        if (!wasDashed && isPressedDash)
        {
            wasDashed = true;
            // 关闭玩家移动、跳跃功能
            _moveEnabled = false;
            _jumpEnabled = false;
            _gravityEnabled = false;
            // 关闭重力影响
            rb.gravityScale = 0;
            // 将速度清零
            rb.velocity = Vector2.zero;
            // 施加力
            rb.velocity += DashDirection() * playerData.dashForce;
            // 施加空气阻力
            DOVirtual.Float(playerData.dragForce, 0, playerData.dragDuration, (drag) =>
            {
                rb.drag = drag;
                // 当阻力减少到0时，开启玩家的移动、跳跃功能，并恢复重力影响
                if (drag == 0)
                {
                    Debug.Log("DOVirtual to 0");
                    _moveEnabled = true;
                    _jumpEnabled = true;
                    _gravityEnabled = true;
                    rb.gravityScale = 1;
                }
            });
        }

        if (isOnGround && !isPressedDash)
        {
            wasDashed = false;
        }
    }

    void Hurt()
    {
        if (!isHitting)
        {
            return;
        }
        Vector2 xVect = _playerHurtOnLeft ? Vector2.left : Vector2.right;
        rb.velocity = new Vector2(xVect.x * 1.2f, rb.velocity.y);
    }



    bool CheckOnGround()
    {
        Collider2D hitCollider = Physics2D.OverlapBox((Vector2)transform.position + playerData.centerPointOffset, playerData.overlapBoxSize, 0, playerData.groundLayerMask);
        return hitCollider != null;
    }

    bool IsInputDash()
    {
        return Input.GetAxisRaw("Dash") != 0;
    }

    Vector2 DashDirection()
    {
        Vector2 direction = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
        if (direction == Vector2.zero)
        {
            if (isFaceToRight)
            {
                direction.x = 1f;
            }
            else
            {
                direction.x = -1f;
            }
        }
        return direction;
    }
}
